#include "./rtx_memory.h"
#include "../mem_inner.h"
#include "loger.h"

/* 内存管理-RTX5 */

#if defined (CONFIG_MEM_TYPE_RTX5)

/* define */
#define TAG "RTX5-PORT"

/* static var */

/* static sal func */


static void *_init(void *obj, void *addr_start, void *addr_end)
{
    _rtx5_obj_t *rtx5_obj = obj;
    size_t size;

    if (obj == NULL) return NULL;

    if (addr_start >= addr_end)
    {
        return NULL;
    }
    else
    {
        size = (uint32_t)addr_end - (uint32_t)addr_start;
    }

    if (rtx5_obj->addr == NULL)
    {
        rtx5_obj->addr = addr_start;
        osRtxMemoryInit(rtx5_obj->addr, size);
        rtx5_obj->head = MemHeadPtr(rtx5_obj->addr);
    }

    LOG_I(TAG, "mem_rtx5_sal init 0x%08X = (0x%08X - 0x%08X)", (uint32_t)rtx5_obj->head, (uint32_t)addr_start, (uint32_t)addr_end);

    return rtx5_obj;
}

static void _free(void *obj, void *ptr)
{
    _rtx5_obj_t *rtx5_obj = obj;
    if (obj)
    {
        osRtxMemoryFree(rtx5_obj->addr, ptr);
    }
}

static void *_malloc(void *obj, size_t bytes)
{
    _rtx5_obj_t *rtx5_obj = obj;
    void *ptr = NULL;

    if (obj)
    {
        ptr = osRtxMemoryAlloc(rtx5_obj->addr, bytes, 0);
    }
    return ptr;
}

static void *_realloc(void *obj, void *ptr, size_t bytes)
{
    _rtx5_obj_t *rtx5_obj = obj;
    void *pp;

    if (obj == NULL) return NULL;
    
    /* Allocate area of requested size. */
    pp = osRtxMemoryAlloc(rtx5_obj->addr, bytes, 0);

    /* If no memory, keep existing block and indicate failure to reallocate. */
    if (pp == NULL) return pp;

    /* Copy existing block if we were given one. */
    if (ptr)
    {
        /* Make copy of data. */
        memcpy(pp, ptr, bytes);

        /* And we're done with the original block. */
        osRtxMemoryFree(rtx5_obj->addr, ptr);
    }

    /* Return newly allocated block. */
    return pp;
}


static void _get_info(void *obj, uint32_t *total, uint32_t *used, uint32_t *max_used)
{
    _rtx5_obj_t *rtx5_obj = obj;
    *total = rtx5_obj->head->size;
    *used = rtx5_obj->head->used;
    *max_used = rtx5_obj->head->used;

}

/* export */

const _mem_sal_opt mem_rtx5_sal_opt = 
{
    .name = "RTX5",
    .func_init = _init,
    .func_free = _free,
    .func_malloc = _malloc,
    .func_realloc = _realloc,
    .func_get_info = _get_info,
};

#endif // CONFIG_MEM_TYPE_RTX5

